/*
* 剪枝方法
* 1.优化搜索顺序：优先搜枝条少的搜索子树
* 2.排除等效冗余：不考虑顺序->使用组合的方式搜索
* 3.可行性剪枝:不符合规则，直接剪枝
* 4.最优化剪枝：不是最优解，直接剪枝
* 5.记忆化搜索：DP
*/
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// #define ONLINE_GUDGE
const int N = 19;
int n, W; // 小猫数量 单辆缆车最大承重
int cat[N];
int cab[N]; // 每辆缆车承重量
int ans = N; 


void dfs(int u, int res) // 第u只小猫 当前解（剪枝），已用res辆,即正在用第res辆车
{
    if(res >= ans) return; // 如果当前解不是最优解
    if(u > n) {ans = min(ans, res); return;}  // 猫已上完

    for(int i = 1; i <= res; i++) // 遍历哪一辆车放得下
    {
        if(cab[i] + cat[u] <= W)
        {
            cab[i] += cat[u];
            
            /*
            printf("infor[u:%d res:%d]Cab: ", u, res);

            for(int i = 1; i <= res; i++) cout << cab[i] << ' ';
            cout << endl;
            */

            dfs(u + 1, res); // 搜索下一只猫 车的数量仍然是res
            cab[i] -= cat[u]; // 恢复现场
        }
    }
    cab[res+1] = cat[u]; // 新开一辆车
    /*
    printf("outfor[u:%d res:%d]Cab: ", u, res);

    for(int i = 1; i <= res; i++) cout << cab[i] << ' ';
        cout << endl;
    */

    dfs(u + 1, res + 1); // 搜索下一只猫 车的数量是res + 1
    cab[res+1] = 0; // 恢复现场

}

int main()
{
    #ifdef ONLINE_GUDGE

    #else
        freopen("./in.txt", "r", stdin);
    #endif
    ios::sync_with_stdio(0); cin.tie(0);

    cin >> n >> W;
    for(int i = 1; i <= n; i++) cin >> cat[i];

    sort(cat+1, cat+n+1, greater<int>());


    dfs(1, 1);
    
    cout << ans << endl;
    
    return 0;
}